/*
* Copyright (c) 2009, Vladimir Gumenuk
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of the copyright holder nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

// FileSearch.cpp: implementation of the CFileSearch class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "FileSearch.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CFileSearch::CFileSearch( LPCTSTR lpstrFolder, LPCTSTR lpstrExt )
{
    if( !lpstrFolder || !lpstrExt )
        return;

    m_hSearch = NULL;
    _tcscpy( m_szDir, lpstrFolder );
    _tcscpy( m_szExt, lpstrExt );
}

CFileSearch::~CFileSearch()
{
    if( m_hSearch )
    {
        ::FindClose( m_hSearch );
        m_hSearch = NULL;
    }
}

BOOL CFileSearch::FindNextFile()
{
    m_bIsFolder = FALSE;

    if( !m_hSearch )
    {
        TCHAR szDir[MAX_PATH];
        _tcscpy( szDir, m_szDir );
        _tcscat( szDir, _T("\\") );
        _tcscat( szDir, m_szExt );
        m_hSearch = ::FindFirstFile( szDir, &m_FileData );
        if( m_hSearch != INVALID_HANDLE_VALUE ) {
        
            if( _tcscmp( m_FileData.cFileName, _T(".") ) == 0 ) {
                if( !::FindNextFile( m_hSearch, &m_FileData ) ) {
                    TRACE( _T("CFileSearch::FindNextFile -> last error: %d\n"), GetLastError() );
                    if( ( GetLastError() == ERROR_NO_MORE_FILES ) || ( m_hSearch == INVALID_HANDLE_VALUE ) )
                        SetLastError( 0 );
                    return FALSE;
                }
            }

            if( _tcscmp( m_FileData.cFileName, _T("..") ) == 0 ) {
                if( !::FindNextFile( m_hSearch, &m_FileData ) ) {
                    TRACE( _T("CFileSearch::FindNextFile -> last error: %d\n"), GetLastError() );
                    if( ( GetLastError() == ERROR_NO_MORE_FILES ) || ( m_hSearch == INVALID_HANDLE_VALUE ) )
                        SetLastError( 0 );
                    return FALSE;
                }
            }
        }
        else
            return FALSE;
    }
    else
    {
        ::FindNextFile( m_hSearch, &m_FileData );
        if( ( GetLastError() == ERROR_NO_MORE_FILES ) || ( m_hSearch == INVALID_HANDLE_VALUE ) )
        {
            SetLastError( 0 );
            ::FindClose( m_hSearch ); // close search
            m_hSearch = NULL;
            return FALSE;
        }
    }

    _tcscpy( m_szSearchPath, m_szDir );
    _tcscat( m_szSearchPath, _T("\\") );
    _tcscat( m_szSearchPath, m_FileData.cFileName );
    
    DWORD dwAttr = ::GetFileAttributes( m_szSearchPath );

    if( dwAttr == INVALID_FILE_ATTRIBUTES )
        return FALSE;

    if( dwAttr & FILE_ATTRIBUTE_DIRECTORY )
        m_bIsFolder = TRUE;

    return TRUE;
}

BOOL CFileSearch::IsFolderExist( LPCTSTR lpstrPath )
{
    if( !lpstrPath )
        return FALSE;

    DWORD dwAttr = ::GetFileAttributes( lpstrPath );

    if( dwAttr == INVALID_FILE_ATTRIBUTES )
        return FALSE;

    if( dwAttr & FILE_ATTRIBUTE_DIRECTORY )
        return TRUE;
    return FALSE;
}

BOOL CFileSearch::IsFileExist( LPCTSTR lpstrFileName )
{
    ATLASSERT( lpstrFileName );

    DWORD dwAttr = ::GetFileAttributes( lpstrFileName );

    if( dwAttr == -1 )
        return FALSE;

    if( dwAttr & FILE_ATTRIBUTE_DIRECTORY )
        return FALSE;

    return TRUE;
}

DATE CFileSearch::GetCreationDate()
{
    return FileTime2VariantDate( &m_FileData.ftCreationTime );
}

DATE CFileSearch::GetLastAccessDate()
{
    return FileTime2VariantDate( &m_FileData.ftLastAccessTime );
}

DATE CFileSearch::GetLastWriteDate()
{
    return FileTime2VariantDate( &m_FileData.ftLastWriteTime );
}

DWORD CFileSearch::GetFileLength()
{
    DWORD dwSize = 0;
    HANDLE hFile = CreateFile( m_szSearchPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
    if( hFile != INVALID_HANDLE_VALUE )
    {
        dwSize = SetFilePointer( hFile, 0, NULL, FILE_END );
        CloseHandle( hFile );
    }
    return dwSize;
}

DWORD CFileSearch::GetFileLength( LPCTSTR lpstrFileName )
{
    if( !lpstrFileName )
        return 0;

    DWORD dwSize = 0;
    HANDLE hFile = CreateFile( lpstrFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
    if( hFile != INVALID_HANDLE_VALUE )
    {
        dwSize = SetFilePointer( hFile, 0, NULL, FILE_END );
        CloseHandle( hFile );
    }
    return dwSize;
}

DWORD CFileSearch::GetFileLength( HANDLE hFile )
{
    if( !hFile || hFile == INVALID_HANDLE_VALUE )
        return 0;

    DWORD dwSize = 0;
    SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
    dwSize = SetFilePointer( hFile, 0, NULL, FILE_END );
    SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
    return dwSize;
}